package com.linkoog.devtools.type;

import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiField;
import com.linkoog.devtools.type.impl.IgnoreType;
import com.linkoog.devtools.type.impl.LiteralTypes;

import java.util.List;
import java.util.Map;

public class TypeParserUtils {

    public static boolean isCollectionType(PsiClass psiClass){
        if ("java.util.List".equals(psiClass.getQualifiedName())) {
            return true;
        }

        if ( "java.util.Collection".equals(psiClass.getQualifiedName())){
            return true;
        }

        return isSubType(psiClass,"java.util.List", "java.util.Collection", "java.lang.Iterable");
    }

    public static boolean isMapType(PsiClass psiClass){
        if ("java.util.Map".equals(psiClass.getQualifiedName())){
            return true;
        }

        return isSubType(psiClass,"java.util.Map");
    }

    public static boolean isFileType(PsiClass psiClass){
        String qualifiedName = psiClass.getQualifiedName();
        if ("org.springframework.web.multipart.MultipartFile".equals(qualifiedName)){
            return true;
        }

        return isSubType(psiClass,"org.springframework.web.multipart.MultipartFile");
    }

    /**
     *   是否为 Number、CharSequence、Temporal的派生类
     */
    public static LiteralType parseDerivativeLiteralType(PsiClass psiClass){
        if (isSubType(psiClass,"java.lang.Number")) {
            return LiteralTypes.IntegerPrimitiveType;
        } else if (isSubType(psiClass,"java.lang.CharSequence")) {
            return LiteralTypes.StringLiteralType;
        } else if (isSubType(psiClass,"java.time.temporal.Temporal")){
            return LiteralTypes.DateLiteralType;
        }

        return null;
    }

    public static boolean isSubType(PsiClass psiClass, String... superQualifiedNames){
        PsiClass[] superPsiClass =  psiClass.getSupers();
        for (PsiClass clazz : superPsiClass) {
            for (String superQualifiedName : superQualifiedNames) {
                if (superQualifiedName.equals(clazz.getQualifiedName())){
                    return true;
                }
            }
        }
        return false;
    }

    public static boolean hasValidationAnno(PsiField psiField){
        return psiField.hasAnnotation("javax.validation.constraints.NotNull")
                || psiField.hasAnnotation("javax.validation.constraints.NotEmpty")
                || psiField.hasAnnotation("javax.validation.constraints.NotBlank");
    }

    public static IgnoreType ignoreTypeParser(String qualifiedName){
        List<IgnoreTypeProvider> extensionList = IgnoreTypeProvider.EXTENSION_POINT_NAME.getExtensionList();
        for (IgnoreTypeProvider ignoreTypeProvider : extensionList) {
            Map<String, String> ignoreTypes = ignoreTypeProvider.getIgnoreTypes();
            if (ignoreTypes.containsKey(qualifiedName)) {
                String typeName = ignoreTypes.get(qualifiedName);
                return new IgnoreType(typeName, qualifiedName);
            }
        }
        return null;
    }
}
